package lc.oa.net.http.request;

import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;

import java.io.UnsupportedEncodingException;
import java.util.Map;

/**
 * 服务端响应格式必须是
 * Content-Type --->application/json
 *
 * @param <T>
 */
public class GsonRequest<T> extends Request<T> {
    private final Gson gson = new Gson();
    private final Class<T> clazz;
    private  Map<String, String> headers=null;
    private final Response.Listener<T> listener;

    /**
     * 构造一个get请求队列
     * Make a GET request and return a parsed object from JSON.
     *
     * @param url     请求URL URL of the request to make
     * @param clazz   响应实体 Relevant class object, for Gson's reflection
     * @param headers 响应header,非必填 Map of request headers
     * @param sucessListener 成功逻辑处理
     * @param errorListener 错误逻辑处理
     */
    public GsonRequest(String url, Class<T> clazz, Map<String, String> headers,
                       Response.Listener<T> sucessListener, Response.ErrorListener errorListener) {
        super(Method.GET, url, errorListener);
        this.clazz = clazz;
        this.headers = headers;
        this.listener = sucessListener;
    }

    /**
     * 构造一个请求队列
     * Make a GET request and return a parsed object from JSON.
     *
     * @param url    请求URL URL of the request to make
     * @param method Request.Method.GET
     * @param clazz  响应实体 Relevant class object, for Gson's reflection
     * @param sucessListener 成功逻辑处理
     * @param errorListener 错误逻辑处理
     */
    public GsonRequest(String url, int method, Class<T> clazz,
                       Response.Listener<T> sucessListener, Response.ErrorListener errorListener) {
        super(method, url, errorListener);
        this.clazz = clazz;
        this.listener = sucessListener;
    }

    /**
     * 构造一个post请求队列
     * Make a GET request and return a parsed object from JSON.
     *
     * @param url   请求URL URL of the request to make
     * @param clazz 响应实体 Relevant class object, for Gson's reflection
     * @param sucessListener 成功逻辑处理
     * @param errorListener 错误逻辑处理
     */
    public GsonRequest(String url, Class<T> clazz,
                       Response.Listener<T> sucessListener, Response.ErrorListener errorListener) {
        super(Method.POST, url, errorListener);
        this.clazz = clazz;
        this.listener = sucessListener;
    }

    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        return headers != null ? headers : super.getHeaders();
    }

    @Override
    protected void deliverResponse(T response) {
        listener.onResponse(response);
    }

    final String contentType = "Content-Type";
    final String contextTypeJson = "application/json;charset=UTF-8";
    final String contextTypePlain = "text/plain;charset=UTF-8";
    final String contextTypeXhtml="application/xhtml+xml;charset=UTF-8";

    @Override
    protected Response<T> parseNetworkResponse(NetworkResponse response) {
        try {
            Map<String, String> header = response.headers;
            String result = new String(
                    response.data,
                    HttpHeaderParser.parseCharset(response.headers));
            //标准Json格式处理
            if (header.get(contentType).contains(contextTypeJson)) {
                return Response.success(
                        gson.fromJson(result, clazz),
                        HttpHeaderParser.parseCacheHeaders(response));
            } else if (header.get(contentType).contains(contextTypePlain)
            || header.get(contentType).contains(contextTypeXhtml)) {
                //T resultObject=gson.fromJson(result,clazz);
//                ByteArrayInputStream byteIn = new ByteArrayInputStream(result.getBytes("UTF-8"));
//                ObjectInputStream objIn = new ObjectInputStream(byteIn);
//                T obj = (T) objIn.readObject();
//                // return obj;
//                return Response.success(obj,
//                        HttpHeaderParser.parseCacheHeaders(response));
                ObjectMapper mapper = new ObjectMapper();
                T obj = mapper.convertValue(result, clazz);
                return Response.success(obj, HttpHeaderParser.parseCacheHeaders(response));

            } else {
                Exception nonJsonFormatException = new Exception("非Json格式!响应内容为--->" + result);
                return Response.error(new ParseError(nonJsonFormatException));
            }

        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JsonSyntaxException e) {
            return Response.error(new ParseError(e));
        }
    }
}
